<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>路由 | Orange框架</title>
    <meta name="generator" content="VuePress 1.9.10">
    <link rel="icon" href="/orange_doc/images/logo.jpg">
    <script>
            var _hmt = _hmt || [];
			(function() {
			  var hm = document.createElement("script");
			  hm.src = "https://hm.baidu.com/hm.js?a0c745d027acbd6848330c087669dc94";
			  var s = document.getElementsByTagName("script")[0]; 
			  s.parentNode.insertBefore(hm, s);
			})();
			</script>
    <meta name="description" content="orange框架,简洁高效的web开发框架, Golang用户极速开发体验。">
    <meta description="orange框架,简洁高效的web开发框架, Golang用户极速开发体验。">
    
    <link rel="preload" href="/orange_doc/assets/css/0.styles.4198b232.css" as="style"><link rel="preload" href="/orange_doc/assets/js/app.e323b7be.js" as="script"><link rel="preload" href="/orange_doc/assets/js/2.8ffd84cf.js" as="script"><link rel="preload" href="/orange_doc/assets/js/1.d3b0779f.js" as="script"><link rel="preload" href="/orange_doc/assets/js/42.4126b76f.js" as="script"><link rel="prefetch" href="/orange_doc/assets/js/10.d11338bf.js"><link rel="prefetch" href="/orange_doc/assets/js/11.03586221.js"><link rel="prefetch" href="/orange_doc/assets/js/12.8f3f5530.js"><link rel="prefetch" href="/orange_doc/assets/js/13.6489b7e0.js"><link rel="prefetch" href="/orange_doc/assets/js/14.3df437f3.js"><link rel="prefetch" href="/orange_doc/assets/js/15.be27f4ba.js"><link rel="prefetch" href="/orange_doc/assets/js/16.ea700694.js"><link rel="prefetch" href="/orange_doc/assets/js/17.a85dc572.js"><link rel="prefetch" href="/orange_doc/assets/js/18.359b700c.js"><link rel="prefetch" href="/orange_doc/assets/js/19.1ed550c9.js"><link rel="prefetch" href="/orange_doc/assets/js/20.067f2700.js"><link rel="prefetch" href="/orange_doc/assets/js/21.c8159272.js"><link rel="prefetch" href="/orange_doc/assets/js/22.3927f69e.js"><link rel="prefetch" href="/orange_doc/assets/js/23.64866326.js"><link rel="prefetch" href="/orange_doc/assets/js/24.405e9861.js"><link rel="prefetch" href="/orange_doc/assets/js/25.3f633c9f.js"><link rel="prefetch" href="/orange_doc/assets/js/26.26fdfa66.js"><link rel="prefetch" href="/orange_doc/assets/js/27.91b3d914.js"><link rel="prefetch" href="/orange_doc/assets/js/28.cd43e5e2.js"><link rel="prefetch" href="/orange_doc/assets/js/29.b587e0e0.js"><link rel="prefetch" href="/orange_doc/assets/js/3.36478a47.js"><link rel="prefetch" href="/orange_doc/assets/js/30.30aeda31.js"><link rel="prefetch" href="/orange_doc/assets/js/31.e61a62f2.js"><link rel="prefetch" href="/orange_doc/assets/js/32.124d2d7c.js"><link rel="prefetch" href="/orange_doc/assets/js/33.24b9dcd3.js"><link rel="prefetch" href="/orange_doc/assets/js/34.a5c00fc8.js"><link rel="prefetch" href="/orange_doc/assets/js/35.a7e238db.js"><link rel="prefetch" href="/orange_doc/assets/js/36.42c5fbe4.js"><link rel="prefetch" href="/orange_doc/assets/js/37.e014361d.js"><link rel="prefetch" href="/orange_doc/assets/js/38.5c677c29.js"><link rel="prefetch" href="/orange_doc/assets/js/39.d9324044.js"><link rel="prefetch" href="/orange_doc/assets/js/4.7e9344c8.js"><link rel="prefetch" href="/orange_doc/assets/js/40.b4486e63.js"><link rel="prefetch" href="/orange_doc/assets/js/41.daf98a13.js"><link rel="prefetch" href="/orange_doc/assets/js/43.d232e117.js"><link rel="prefetch" href="/orange_doc/assets/js/44.324be1ea.js"><link rel="prefetch" href="/orange_doc/assets/js/45.6d5645a4.js"><link rel="prefetch" href="/orange_doc/assets/js/46.8127c460.js"><link rel="prefetch" href="/orange_doc/assets/js/47.6a6a20c1.js"><link rel="prefetch" href="/orange_doc/assets/js/48.538157de.js"><link rel="prefetch" href="/orange_doc/assets/js/49.ab9e2921.js"><link rel="prefetch" href="/orange_doc/assets/js/5.45a5aec7.js"><link rel="prefetch" href="/orange_doc/assets/js/50.8ad7176f.js"><link rel="prefetch" href="/orange_doc/assets/js/6.43fcf2a3.js"><link rel="prefetch" href="/orange_doc/assets/js/7.569ec916.js"><link rel="prefetch" href="/orange_doc/assets/js/vendors~docsearch.9170ad82.js">
    <link rel="stylesheet" href="/orange_doc/assets/css/0.styles.4198b232.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/orange_doc/" class="home-link router-link-active"><img src="/orange_doc/images/logo.jpg" alt="Orange框架" class="logo"> <span class="site-name can-hide">Orange框架</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/orange_doc/" class="nav-link">
  首页
</a></div><div class="nav-item"><a href="/orange_doc/快速开始.html" class="nav-link">
  快速开始
</a></div><div class="nav-item"><a href="/orange_doc/about.html" class="nav-link">
  文档
</a></div><div class="nav-item"><a href="https://www.kancloud.cn/chase688/orange_framework" target="_blank" rel="noopener noreferrer" class="nav-link external">
  看云镜像
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://gitee.com/zhucheer/orange" target="_blank" rel="noopener noreferrer" class="nav-link external">
  源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/orange_doc/" class="nav-link">
  首页
</a></div><div class="nav-item"><a href="/orange_doc/快速开始.html" class="nav-link">
  快速开始
</a></div><div class="nav-item"><a href="/orange_doc/about.html" class="nav-link">
  文档
</a></div><div class="nav-item"><a href="https://www.kancloud.cn/chase688/orange_framework" target="_blank" rel="noopener noreferrer" class="nav-link external">
  看云镜像
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://gitee.com/zhucheer/orange" target="_blank" rel="noopener noreferrer" class="nav-link external">
  源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div> <!----></nav>  <ul class="sidebar-links"><li><a href="/orange_doc/快速开始.html" class="sidebar-link">快速开始</a></li><li><a href="/orange_doc/config/配置.html" class="sidebar-link">配置</a></li><li><a href="/orange_doc/log/日志.html" class="sidebar-link">日志</a></li><li><a href="/orange_doc/config/命令行参数.html" class="sidebar-link">命令行参数</a></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>请求与响应</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/orange_doc/route/路由.html" class="active sidebar-link">路由</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#介绍" class="sidebar-link">介绍</a></li><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#使用说明" class="sidebar-link">使用说明</a></li><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#定义路由组" class="sidebar-link">定义路由组</a></li><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#路由定义" class="sidebar-link">路由定义</a></li><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#路由注入" class="sidebar-link">路由注入</a></li><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#完整示例" class="sidebar-link">完整示例</a></li><li class="sidebar-sub-header"><a href="/orange_doc/route/路由.html#其他说明" class="sidebar-link">其他说明</a></li></ul></li><li><a href="/orange_doc/route/静态资源绑定.html" class="sidebar-link">静态资源绑定</a></li><li><a href="/orange_doc/route/中间件.html" class="sidebar-link">中间件</a></li><li><a href="/orange_doc/controller/控制器.html" class="sidebar-link">控制器</a></li><li><a href="/orange_doc/request/Session.html" class="sidebar-link">Session</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>数据库</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/orange_doc/DB/Mysq操作.html" class="sidebar-link">Mysq操作</a></li><li><a href="/orange_doc/DB/Redis操作.html" class="sidebar-link">Redis操作</a></li></ul></section></li><li><a href="/orange_doc/view.html" class="sidebar-link">视图</a></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>其他</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/orange_doc/base/项目目录.html" class="sidebar-link">项目目录</a></li><li><a href="/orange_doc/base/项目编译.html" class="sidebar-link">项目编译</a></li><li><a href="/orange_doc/base/优雅退出.html" class="sidebar-link">优雅退出</a></li><li><a href="/orange_doc/base/平滑重启.html" class="sidebar-link">平滑重启</a></li><li><a href="/orange_doc/base/pprof支持.html" class="sidebar-link">pprof支持</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>实用工具</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/orange_doc/tools/图片验证码.html" class="sidebar-link">图片验证码</a></li><li><a href="/orange_doc/tools/简单队列.html" class="sidebar-link">简单队列</a></li><li><a href="/orange_doc/tools/消息队列.html" class="sidebar-link">消息队列</a></li><li><a href="/orange_doc/tools/http请求客户端.html" class="sidebar-link">http请求客户端</a></li><li><a href="/orange_doc/tools/文件上传.html" class="sidebar-link">文件上传</a></li><li><a href="/orange_doc/tools/发送邮件.html" class="sidebar-link">发送邮件</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="路由"><a href="#路由" class="header-anchor">#</a> 路由</h1> <h2 id="介绍"><a href="#介绍" class="header-anchor">#</a> 介绍</h2> <p>Orange 框架中的路由接管了 http 包中的路由查找，提供了路由群组，表达式路由等多种策略，提高了灵活性；存储模型参考了 Echo 框架，采用了类似 Radix tree 的多路查找树模型，有较好的路由查找效率，尤其在有大量表达式路由时相比正则匹配优势比较明显；同时也能很好的解决哈希存储的哈希冲突问题。</p> <h2 id="使用说明"><a href="#使用说明" class="header-anchor">#</a> 使用说明</h2> <p>路由文件默认在 http/routes.go 中声明。
路由定义需要通过结构体实现 <code>app.AppSrv</code> 接口，即接口体中需要有 <code>func (s *Route) ServeMux()</code> 和 <code>func (s *Route) Register()</code>  方法。</p> <p>ServeMux 方法用户定义路由信息，Register方法用于初始化启动自定义服务，和 init 方法的区别是，Register方法在框架相关组件加载完成后再执行，避免了一些空指针的情况。</p> <h2 id="定义路由组"><a href="#定义路由组" class="header-anchor">#</a> 定义路由组</h2> <p>通过路由组可以定义有相同前缀url和执行相同中间件的一类路由；
通过 <code>groupName := app.GroupRouter(&quot;/api&quot;, NewMiddleWare1(), NewMiddleWare2)</code> 来实现；</p> <h2 id="路由定义"><a href="#路由定义" class="header-anchor">#</a> 路由定义</h2> <ul><li>定义GET请求  <code>groupName .GET(&quot;/upload&quot;, controller.Upload)</code></li> <li>定义POST请求  <code>groupName .POST(&quot;/upload&quot;, controller.Upload)</code></li> <li>定义接受所有请求  <code>groupName .ALL(&quot;/upload&quot;, controller.Upload)</code></li></ul> <h3 id="静态路由"><a href="#静态路由" class="header-anchor">#</a> 静态路由</h3> <p>静态路由是定义一个固定的访问地址，需url和路由信息完全匹配；
如：<code>groupName .GET(&quot;/upload&quot;, controller.Upload)</code>，访问时 url 必须是 /upload；</p> <h3 id="表达式-参数路由"><a href="#表达式-参数路由" class="header-anchor">#</a> 表达式-参数路由</h3> <p>参数路由会将定义的参数设置成变量，匹配到相应格式即可；
如：<code>groupName .GET(&quot;/userinfo/:uid&quot;, controller.UserInfo)</code> ，访问时 url 是 /userinfo/1，/userinfo/2， /userinfo/199 等等；</p> <h3 id="表达式-全匹配路由"><a href="#表达式-全匹配路由" class="header-anchor">#</a> 表达式-全匹配路由</h3> <p>类似与模糊匹配，url 只需要前缀一致即可匹配；
如：<code>groupName .GET(&quot;/userhome/*&quot;, controller.UserHome)</code>
访问时 url 是 /userhome/001，/userhome/001/find， /userinfo/get/101 等等，后面多个斜线也都能匹配上；</p> <h3 id="匹配优先级"><a href="#匹配优先级" class="header-anchor">#</a> 匹配优先级</h3> <p>在多种路由同时定义时，可能会出现模糊匹配覆盖其他类型的情况，我们定义了一套符合常理的优先级；
静态路由 &gt; 参数路由 &gt; 全匹配路由</p> <h2 id="路由注入"><a href="#路由注入" class="header-anchor">#</a> 路由注入</h2> <p>在项目入口文件中，将路由结构体传入app启动方法，如下：</p> <div class="language- extra-class"><pre class="language-text"><code>

func main() {

   router := &amp;http.Route{}
   app.AppStart(router)

}

</code></pre></div><h2 id="完整示例"><a href="#完整示例" class="header-anchor">#</a> 完整示例</h2> <div class="language- extra-class"><pre class="language-text"><code>package http

import (
   &quot;gitee.com/zhucheer/orange/app&quot;
   &quot;gitee.com/zhucheer/orange/project/http/controller&quot;
   &quot;gitee.com/zhucheer/orange/project/http/middleware&quot;
)

type Route struct {
}

func (s *Route) ServeMux() {
   commonGp := app.GroupRouter(&quot;&quot;)  // 定义一个路由组 commonGp
   {
      commonGp.GET(&quot;/&quot;, func(ctx *app.Context) error { //  commonGp 路由组下的一个 GET 请求类型路由 / 
         return ctx.ToJson(map[string]interface{}{&quot;data&quot;: &quot;orange framework&quot;})
      })

      commonGp.ALL(&quot;/upload&quot;, controller.Upload)  //  commonGp 路由组下的一个所有请求类型路由 /upload 
   }

   //  定义路由组 authGp 该路由组会执行一个中间件 Auth 
   authGp := app.GroupRouter(&quot;/auth&quot;, middleware.NewAuth())
   {
      authGp.ALL(&quot;/info&quot;, controller.AuthCheck) // 定义 authGp  路由组下所有请求类型路由 /auth/info
   }

}


func (s *Route) Register() {
}

</code></pre></div><h2 id="其他说明"><a href="#其他说明" class="header-anchor">#</a> 其他说明</h2> <p>在上面完整示例中用到了花括号的另一个用法，有些同学对这里会有点疑惑，我在这里解释解释；</p> <p>在 Golang 中 <code>{ }</code> 花括号的用法除了和其他语言通用的包裹函数体之外还有另外一个用途，那就是可以通过花括号来区分代码块，将业务相对独立的代码区域进行分割，上述路由示例中就是这种用法；因此它也没有不能另起一行定义的限制；这里需要大家理解；</p> <p><strong>值得注意的是</strong>，代码块中申明的变量作用域仅在块中生效，这样可以将不同的路由群组进行有效的区分，提高代码的可读性，减少因变量泛滥引起的问题；</p> <p>有同学可能会问，&quot;为什么不封装成函数?&quot; 当然，封装成函数固然也是一种方法，这也正是 Golang 的编程思想，“简单，灵活”； 如果业务模块庞大，根据不同文件不同包来区分各类路由组也都是可以的，取决于你对自己业务的把控。</p></div> <footer class="page-edit"><!----> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/orange_doc/config/命令行参数.html" class="prev">
        命令行参数
      </a></span> <span class="next"><a href="/orange_doc/route/静态资源绑定.html">
        静态资源绑定
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/orange_doc/assets/js/app.e323b7be.js" defer></script><script src="/orange_doc/assets/js/2.8ffd84cf.js" defer></script><script src="/orange_doc/assets/js/1.d3b0779f.js" defer></script><script src="/orange_doc/assets/js/42.4126b76f.js" defer></script>
  </body>
</html>
